﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Zero.Core.Domain;
using Zero.Core.Domain.Query;
using Zero.DataLayer;
using Zero.DataLayer.Donnees;
using Zero.POCO;
using Zero.POCO.Compagne;
using Zero.POCO.Donnees;
using Zero.POCO.Enum;
using Zero.POCO.Enum.Helper.Support;
using Zero.POCO.Helper.Support;
using Zero.POCO.Interfaces;
using Zero.POCO.Support;
using Zero.Presenter.Donnees;
using TypeMedia = Zero.POCO.Compagne.TypeMedia;
using Vague = Zero.POCO.Donnees.Vague;

namespace Zero.Presenter
{
    public class CampagnePresenter:ICampagnePresenter
    {
        private ICampagneView compView;
        private IRepository<Compaign, Guid> campagneRepository;

        public CampagnePresenter(ICampagneView campagne, IRepository<Compaign,Guid> repository )
        {
            compView = campagne;
            campagneRepository = repository;
        }

        public void Display(){
            compView.campagnes = campagneRepository.FindAll().ToList();
        }

        public void WriteChanges(Compaign compaign)
        {
            campagneRepository.Save(compaign);
        }
    }

    
    
    public interface ICampagnePresenter
    {
        void Display();
        void WriteChanges(Compaign compaign);
    }

    public interface ICampagneView
    {
        List<Compaign> campagnes { get; set; }
    }





    public class InsertionPresenter:IInsertionPresenter
    {
        private IInsertionView _insertView;
        private IRepository<PlanPresse, Guid> _planPresseRepository;
        private IRepository<PlanTV, Guid> _planTvRepository;
        private IRepository<PlanRadio, Guid> _planRadioRepository;

        public InsertionPresenter(IInsertionView InsertView, IRepository<PlanPresse, Guid> planPresseRepository, IRepository<PlanTV, Guid> planTvRepository, IRepository<PlanRadio, Guid> planRadioRepository)
        {
            _insertView = InsertView;
            _planPresseRepository = planPresseRepository;
            _planTvRepository = planTvRepository;
            _planRadioRepository = planRadioRepository;
        }

        public void Display()
        {
            //_planPresseRepository
        }

    

        public void WriteChanges(IEnumerable<InsertionView> insertionViews, List<SupportTV> supportTvs,List<SupportRadio> supportRadios,List<SupportPresse> supportPresses, PlanTV planTV = null,PlanRadio planRadio = null,PlanPresse planPresse = null)
        {
            List<InsertionTv> _listTv=new List<InsertionTv>();
            List<InsertionPresse> _listPr=new List<InsertionPresse>();
            List<InsertionRadio> _listRd=new List<InsertionRadio>();

            foreach (var insertionView in insertionViews)
            {
                switch (insertionView.TypeMedia)
                {
                    case TypeMedia.TV:
                    {
                        var insertiontv = new InsertionTv();
                        insertiontv.Date = new DateTime(insertionView.Start.Year, insertionView.Start.Month, insertionView.Start.Day);
                        insertiontv.SupportTv = supportTvs.First(e => e.id == insertionView.Oid);

                        insertiontv.NumeroCinQMinute = insertionView.Finish.Minute/5;
                        insertiontv.NumeroCinQMinute += insertionView.Finish.Hour*12;
                        insertiontv.duree = (int.Parse(insertionView.Duree)+1)*5;
                        _listTv.Add(insertiontv);
                     

                        break;
                    }
                    case TypeMedia.RD:
                    {


                        var insertionRd = new InsertionRadio();
                        insertionRd.Date = new DateTime(insertionView.Start.Year, insertionView.Start.Month, insertionView.Start.Day);
                        insertionRd.SupportRadio = supportRadios.First(e => e.id == insertionView.Oid);
                        insertionRd.NumeroCinQMinute = insertionView.Finish.Minute / 5;
                        insertionRd.NumeroCinQMinute += insertionView.Finish.Hour * 12;
                        insertionRd.Duree = (int.Parse(insertionView.Duree)+1)*5;
                        _listRd.Add(insertionRd);
                        break;
                    }
                    case TypeMedia.PR:
                    {
                        var insertionPr = new InsertionPresse();
                        insertionPr.Date = new DateTime(insertionView.Start.Year, insertionView.Start.Month, insertionView.Start.Day);
                        insertionPr.SupportPresse = supportPresses.First(e => e.id == insertionView.Oid);
                        insertionPr.FormatPresse = (FormatPresse)Enum.Parse(typeof(FormatPresse), insertionView.Duree);
                        _listPr.Add(insertionPr);
                        break;}


                }
                
            }
            if (planTV != null)
            {
                planTV.InsertionTvs = _listTv;
                _planTvRepository.Save(planTV);
            }

            if (planRadio != null)
            {
                planRadio.InsertionRadios = _listRd;
                _planRadioRepository.Save(planRadio);
            }

            if (planPresse != null)
            {
                planPresse.InsertionPresses = _listPr;
                _planPresseRepository.Save(planPresse);
            }
        }

     


        public List<AudienceViewModel> GetAudiences(IRepositoryVague<Vague, Guid> vagueRepository,Filter filter, Vague vague)
        {



            var criterionSignlalitiques = new Criterion("Signalitique", vagueRepository.GetSignalitique(filter, vague), CriteriaOperator.Equal);
            var Query = new Query();
            Query.Add(criterionSignlalitiques);

            var adueicensView = vagueRepository.GetAudience(Query, vague);

            return adueicensView;
        }



        public IndicView Process_Indicateur(IRepositoryVague<Vague, int> vagueRepository, IRepositoryPlan<PlanTV, Guid> repositoryPlanTv, IRepositoryPlan<PlanRadio, Guid> repositoryPlanRd, IRepositoryPlan<PlanPresse, Guid> repositoryPlanPr, List<InsertionView> insertionViews, Filter filter, Vague vague, List<SupportTV> supportTvs, List<SupportRadio> supportRadios, List<SupportPresse> supportPresses, PlanTV plantv, PlanRadio planrd, PlanPresse planpr)
        {


            List<InsertionTv> _listTv = new List<InsertionTv>();
            List<InsertionPresse> _listPr = new List<InsertionPresse>();
            List<InsertionRadio> _listRd = new List<InsertionRadio>();


            foreach (var insertionView in insertionViews)
            {





                switch (insertionView.TypeMedia)
                {
                    case TypeMedia.TV:
                        {
                            for (int i = 0; i < 15; i++)
                            {
                                var insertiontv = new InsertionTv();
                                insertiontv.Date = new DateTime(insertionView.Start.Year, insertionView.Start.Month, insertionView.Start.Day);
                                insertiontv.SupportTv = supportTvs.First(e => e.id == insertionView.Oid);

                                insertiontv.NumeroCinQMinute = insertionView.Finish.Minute+i;
                                insertiontv.NumeroCinQMinute += insertionView.Finish.Hour * 12;
                                //insertiontv.NumeroCinQMinute = insertiontv.NumeroCinQMinute%96;
                                insertiontv.duree = (int.Parse(insertionView.Duree) + 1) * 5;
                                _listTv.Add(insertiontv);
                            }

                            


                            break;
                        }
                    case TypeMedia.RD:
                        {


                            var insertionRd = new InsertionRadio();
                            insertionRd.Date = new DateTime(insertionView.Start.Year, insertionView.Start.Month, insertionView.Start.Day);
                            insertionRd.SupportRadio = supportRadios.First(e => e.id == insertionView.Oid);
                            insertionRd.NumeroCinQMinute = insertionView.Finish.Minute / 5;
                            insertionRd.NumeroCinQMinute += insertionView.Finish.Hour * 12;
                            insertionRd.NumeroCinQMinute = insertionRd.NumeroCinQMinute % 96;
                            insertionRd.Duree = (int.Parse(insertionView.Duree) + 1) * 5;
                            _listRd.Add(insertionRd);
                            break;
                        }
                    case TypeMedia.PR:
                        {
                            var insertionPr = new InsertionPresse();
                            insertionPr.Date = new DateTime(insertionView.Start.Year, insertionView.Start.Month, insertionView.Start.Day);
                            insertionPr.SupportPresse = supportPresses.First(e => e.id == insertionView.Oid);
                            insertionPr.FormatPresse = (FormatPresse)Enum.Parse(typeof(FormatPresse), insertionView.Duree);
                            _listPr.Add(insertionPr);
                            break;
                        }


                }

            }





            var planTV = new PlanTV(){
                Name = "test",
                InsertionTvs = _listTv,
                id = Guid.NewGuid()
            };

            var planRd = new PlanRadio()
            {
                Name = "test",
                InsertionRadios = _listRd,
                id = Guid.NewGuid()
            };

            var planPr = new PlanPresse()
            {
                Name = "test",
                InsertionPresses = _listPr,
                id = Guid.NewGuid()
            };



         var criterionTvSupport = new Criterion("planTv", planTV, CriteriaOperator.Equal);
         var criterionRdSupport = new Criterion("planRd", planRd, CriteriaOperator.Equal);
         var criterionPrSupport = new Criterion("planPr", planPr, CriteriaOperator.Equal);
         var criterionSignlalitiques = new Criterion("Signalitique", planTV.GetSignalitique(filter,vague), CriteriaOperator.Equal);
         var Query = new Query();
         Query.Add(criterionTvSupport);
         Query.Add(criterionRdSupport);
         Query.Add(criterionPrSupport);
         Query.Add(criterionSignlalitiques);



         var criterionTarifTv = new Criterion("PlanTv", plantv, CriteriaOperator.Equal);
         var criterionInsertionTv = new Criterion("InsertionTv", _listTv, CriteriaOperator.Equal);
            var querytarifTv = new Query();
            querytarifTv.Add(criterionTarifTv);
            querytarifTv.Add(criterionInsertionTv);

         



         var criterionTarifRd = new Criterion("PlanRd", planrd, CriteriaOperator.Equal);
         var criterionInsertionRd = new Criterion("InsertionRd", _listRd, CriteriaOperator.Equal);
         var querytarifRd = new Query();
         querytarifRd.Add(criterionTarifRd);
         querytarifRd.Add(criterionInsertionRd);




         var criterionTarifPr = new Criterion("PlanPr", planpr, CriteriaOperator.Equal);
         var criterionInsertionPr = new Criterion("InsertionPr", _listPr, CriteriaOperator.Equal);
         var querytarifPr = new Query();
         querytarifPr.Add(criterionInsertionPr);
         querytarifPr.Add(criterionTarifPr);




            var criteriaCompagne = planTV.GetSignalitique(filter, vague);


            float total = criteriaCompagne.Sum(e => e.Poid);

         var indicateur = vagueRepository.GetIndicateurRadioTele(Query, vague);
         var indic = new IndicView();

         var distinct = indicateur.Select(e=>e.Signalitique).Distinct();
            foreach (var guid in distinct)
            {
                indic.Couverture = indic.Couverture +
                                   indicateur.Where(e => e.Signalitique == guid).Select(e => e.poid).FirstOrDefault();
            }
         indic.Tarif = repositoryPlanTv.GetTarif(querytarifTv)+repositoryPlanRd.GetTarif(querytarifRd)+repositoryPlanPr.GetTarif(querytarifPr);
         indic.GRP = indicateur.Sum(d=>d.nbLu);
         indic.Couverture = indic.Couverture/total*100;
         indic.Repetition = indic.GRP/indic.Couverture;
         indic.TotalIndividu = (int)total;
         indic.NombreInsertion = _listTv.Count + _listRd.Count + _listPr.Count;
         indic.Couv3 = 0;

         return indic;
            
        }


        public IndicView Process_Indicateurbis(IRepositoryVague<Vague, int> vagueRepository, IRepositoryPlan<PlanTV, Guid> repositoryPlanTv, IRepositoryPlan<PlanRadio, Guid> repositoryPlanRd, IRepositoryPlan<PlanPresse, Guid> repositoryPlanPr, List<InsertionView> insertionViews, Filter filter, Vague vague, List<SupportTV> supportTvs, List<SupportRadio> supportRadios, List<SupportPresse> supportPresses, PlanTV plantv, PlanRadio planrd, PlanPresse planpr)
        {


            List<InsertionTv> _listTv = new List<InsertionTv>();
            List<InsertionPresse> _listPr = new List<InsertionPresse>();
            List<InsertionRadio> _listRd = new List<InsertionRadio>();


            foreach (var insertionView in insertionViews)
            {





                switch (insertionView.TypeMedia)
                {
                    case TypeMedia.TV:
                        {
                            var insertiontv = new InsertionTv();
                            insertiontv.Date = new DateTime(insertionView.Start.Year, insertionView.Start.Month, insertionView.Start.Day);
                            insertiontv.SupportTv = supportTvs.First(e => e.id == insertionView.Oid);

                            insertiontv.NumeroCinQMinute = insertionView.Finish.Minute / 5;
                            insertiontv.NumeroCinQMinute += insertionView.Finish.Hour * 12;
                            insertiontv.NumeroCinQMinute = insertiontv.NumeroCinQMinute % 96;
                            insertiontv.duree = (int.Parse(insertionView.Duree) + 1) * 5;
                            _listTv.Add(insertiontv);


                            break;
                        }
                    case TypeMedia.RD:
                        {


                            var insertionRd = new InsertionRadio();
                            insertionRd.Date = new DateTime(insertionView.Start.Year, insertionView.Start.Month, insertionView.Start.Day);
                            insertionRd.SupportRadio = supportRadios.First(e => e.id == insertionView.Oid);
                            insertionRd.NumeroCinQMinute = insertionView.Finish.Minute / 5;
                            insertionRd.NumeroCinQMinute += insertionView.Finish.Hour * 12;
                            insertionRd.NumeroCinQMinute = insertionRd.NumeroCinQMinute % 96;
                            insertionRd.Duree = (int.Parse(insertionView.Duree) + 1) * 5;
                            _listRd.Add(insertionRd);
                            break;
                        }
                    case TypeMedia.PR:
                        {
                            var insertionPr = new InsertionPresse();
                            insertionPr.Date = new DateTime(insertionView.Start.Year, insertionView.Start.Month, insertionView.Start.Day);
                            insertionPr.SupportPresse = supportPresses.First(e => e.id == insertionView.Oid);
                            insertionPr.FormatPresse = (FormatPresse)Enum.Parse(typeof(FormatPresse), insertionView.Duree);
                            _listPr.Add(insertionPr);
                            break;
                        }


                }

            }





            var planTV = new PlanTV()
            {
                Name = "test",
                InsertionTvs = _listTv,
                id = Guid.NewGuid()
            };

            var planRd = new PlanRadio()
            {
                Name = "test",
                InsertionRadios = _listRd,
                id = Guid.NewGuid()
            };

            var planPr = new PlanPresse()
            {
                Name = "test",
                InsertionPresses = _listPr,
                id = Guid.NewGuid()
            };



            var criterionTvSupport = new Criterion("planTv", planTV, CriteriaOperator.Equal);
            var criterionRdSupport = new Criterion("planRd", planRd, CriteriaOperator.Equal);
            var criterionPrSupport = new Criterion("planPr", planPr, CriteriaOperator.Equal);
            var criterionSignlalitiques = new Criterion("Signalitique", planTV.GetSignalitique(filter, vague), CriteriaOperator.Equal);
            var Query = new Query();
            Query.Add(criterionTvSupport);
            Query.Add(criterionRdSupport);
            Query.Add(criterionPrSupport);
            Query.Add(criterionSignlalitiques);



            var criterionTarifTv = new Criterion("PlanTv", plantv, CriteriaOperator.Equal);
            var criterionInsertionTv = new Criterion("InsertionTv", _listTv, CriteriaOperator.Equal);
            var querytarifTv = new Query();
            querytarifTv.Add(criterionTarifTv);
            querytarifTv.Add(criterionInsertionTv);





            var criterionTarifRd = new Criterion("PlanRd", planrd, CriteriaOperator.Equal);
            var criterionInsertionRd = new Criterion("InsertionRd", _listRd, CriteriaOperator.Equal);
            var querytarifRd = new Query();
            querytarifRd.Add(criterionTarifRd);
            querytarifRd.Add(criterionInsertionRd);




            var criterionTarifPr = new Criterion("PlanPr", planpr, CriteriaOperator.Equal);
            var criterionInsertionPr = new Criterion("InsertionPr", _listPr, CriteriaOperator.Equal);
            var querytarifPr = new Query();
            querytarifPr.Add(criterionInsertionPr);
            querytarifPr.Add(criterionTarifPr);




            var criteriaCompagne = planTV.GetSignalitique(filter, vague);


            float total = criteriaCompagne.Sum(e => e.Poid);

            var indicateur = vagueRepository.GetIndicateurRadioTele(Query, vague);
            var indic = new IndicView();

            var distinct = indicateur.Select(e => e.Signalitique).Distinct();
            foreach (var guid in distinct)
            {
                indic.Couverture = indic.Couverture +
                                   indicateur.Where(e => e.Signalitique == guid).Select(e => e.poid).FirstOrDefault();
            }
            indic.Tarif = repositoryPlanTv.GetTarif(querytarifTv) + repositoryPlanRd.GetTarif(querytarifRd) + repositoryPlanPr.GetTarif(querytarifPr);
            indic.GRP = indicateur.Sum(d => d.nbLu);
            indic.Couverture = indic.Couverture / total * 100;
            indic.Repetition = indic.GRP / indic.Couverture;
            indic.TotalIndividu = (int)total;
            indic.NombreInsertion = _listTv.Count + _listRd.Count + _listPr.Count;
            indic.Couv3 = 0;

            return indic;

        }



        

    }


    public interface IInsertionPresenter
    {
        void Display();
        void WriteChanges(IEnumerable<InsertionView> insertionViews, List<SupportTV> supportTvs, List<SupportRadio> supportRadios, List<SupportPresse> supportPresses, PlanTV planTV = null, PlanRadio planRadio = null, PlanPresse planPresse = null);
        IndicView Process_Indicateur(IRepositoryVague<Vague, int> vagueRepository, IRepositoryPlan<PlanTV, Guid> repositoryPlanTv, IRepositoryPlan<PlanRadio, Guid> repositoryPlanRd, IRepositoryPlan<PlanPresse, Guid> repositoryPlanPr, List<InsertionView> insertionViews, Filter filter, Vague vague, List<SupportTV> supportTvs, List<SupportRadio> supportRadios, List<SupportPresse> supportPresses, PlanTV plantv, PlanRadio plandrd, PlanPresse planpr);
    }



    public interface IInsertionView
    {
        List<InsertionView> Insertion { get; set; }
    }


   

    public class InsertionView
    {
        public  DateTime Start { get; set; }
        public DateTime Finish { get; set; }
        public String Subject { get; set; }
        public int Oid { get; set; }
        public TypeMedia TypeMedia { get; set; }
        public bool AllDay { get; set; }
        public String Duree { get; set; }

        public String Media { get; set; }
    }


    public class IndicView
    {
        public float Couverture { get; set; }
        public float Repetition { get; set; }
        public float Couv3 { get; set; }
        public int NombreInsertion { get; set; }
        public float GRP { get; set; }
        public int TotalIndividu { get; set; }
        public double Tarif { get; set; }

    }

}
